package cz.pecinovsky.česky.oopnz._115_;
//Příliš žluťoučký kůň úpěl ďábelské ódy

// %I+ <124
//import cz.pecinovsky.česky.oopnz.správce_01_výchozí.IKreslený;
// %I-
import cz.pecinovsky.česky.oopnz.správce.IPosuvný;
import cz.pecinovsky.česky.oopnz.správce.Kreslítko;
import cz.pecinovsky.česky.oopnz.správce.Obdélník;

import cz.pecinovsky.česky.oopnz.utility.Pozice;

import cz.pecinovsky.česky.oopnz.utility.Barva;

import cz.pecinovsky.česky.oopnz.utility.IO;


import static cz.pecinovsky.česky.oopnz._115_.Světlo_120_124.Světlo;

////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ Konec ignorovaného počátečního textu +++++
//%X+ xxxxx Začátek přeskakovaného textu xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   oopnz._115_._116_Semafor_119
 * Následující: Prozatím není
 *
 * Projekt  020z - Komentáře
 *   + Začlenění do standardní šablony + Komentáře
 *
 * Projekt  021z - Použití this
 *   ~ V prvních dvou konstruktorech nahrazena původní těla
 *     příkazem this volajícím obecnější konstruktor
 *
 * Projekt  022z - Přetěžování
 *   + Přidány další dva konstruktory
 *   ~ Ve třetím konstruktoru nahrazeno tělo příkazem this
 *     volající přidaný obecnější konstruktor
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class Semafor_120_124
{    private Semafor_120_124() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- Konec přeskakovaného textu -----


/*******************************************************************************
 * Instance třídy {@code Semafor} představují semafory obdobné těm,
 * které řídí dopravu na křižovatkách.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
//%I+ <124
//public class Semafor implements IKreslený
//%I-
//%X+ <124
public class Semafor implements IPosuvný
//%X-
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================

    /** Krabice, v níž jsou umístěna světla. */
    private Obdélník krabice;

    /** Horní, červené světlo. */
    private Světlo červená;

    /** Střední, žluté (oranžové) světlo. */
    private Světlo žlutá;

    /** Dolní, zelené světlo. */
    private Světlo zelená;



//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     * Vytvoří semafor implicitních rozměrů a barvy
     * umístěný v levém horním rohu plátna.
     */
    public Semafor()
    {
//%I+ <121
//        krabice = new Obdélník(0,   0, 50, 150, Barva.ČERNÁ);
//        červená = new Světlo  (0,   0, Barva.ČERVENÁ);
//        žlutá   = new Světlo  (0,  50, Barva.ŽLUTÁ  );
//        zelená  = new Světlo  (0, 100, Barva.ZELENÁ );
//%I-
//%X+ <121
         this(0, 0);
//%X-
    }


    /***************************************************************************
     * Vytvoří semafor implicitních rozměrů a barvy
     * umístěný na zadané pozici.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     */
    public Semafor(int x, int y)
    {
//%I+ <121
//        krabice = new Obdélník(x, y+  0,  50, 150, Barva.ČERNÁ);
//        červená = new Světlo  (x, y+  0, Barva.ČERVENÁ);
//        žlutá   = new Světlo  (x, y+ 50, Barva.ŽLUTÁ  );
//        zelená  = new Světlo  (x, y+100, Barva.ZELENÁ );
//%I-
//%X+ <121
        this(x, y, Barva.ČERNÁ);
//%X-
    }


    /***************************************************************************
     * Vytvoří semafor implicitních rozměrů s krabicí zadané barvy
     * umístěný na zadané pozici.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param barvaKrabice  Požadovaná barva krabice se světly
     */
    public Semafor(int x, int y, Barva barvaKrabice)
    {
//%I+ <122
//        krabice = new Obdélník(x, y+  0,  50, 150, barvaKrabice);
//        červená = new Světlo  (x, y+  0, Barva.ČERVENÁ);
//        žlutá   = new Světlo  (x, y+ 50, Barva.ŽLUTÁ  );
//        zelená  = new Světlo  (x, y+100, Barva.ZELENÁ );
//    }
//%I-
//%X+ <122
        this(x, y, 50, barvaKrabice);
    }


    /***************************************************************************
     * Vytvoří semafor zadaných rozměrů s krabicí implicitní barvy
     * umístěný na zadaných souřadnicích.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param modul  Šířka semaforu a průměr jeho světel
     */
    public Semafor(int x, int y, int modul)
    {
        this(x, y, modul, Barva.ČERNÁ);
    }


    /***************************************************************************
     * Vytvoří semafor zadaných rozměrů s krabicí zadané barvy
     * umístěný na zadaných souřadnicích.
     *
     * @param x  Vodorovná souřadnice
     * @param y  Svislá souřadnice
     * @param modul         Šířka semaforu a průměr jeho světel
     * @param barvaKrabice  Požadovaná barva krabice se světly
     */
    public Semafor(int x, int y, int modul, Barva barvaKrabice)
    {
        krabice = new Obdélník(x, y,  modul, 3*modul, barvaKrabice);

        červená = new Světlo  (x, y,         modul, Barva.ČERVENÁ, Barva.ŽÁDNÁ);
        žlutá   = new Světlo  (x, y+  modul, modul, Barva.ŽLUTÁ,   Barva.ŽÁDNÁ);
        zelená  = new Světlo  (x, y+2*modul, modul, Barva.ZELENÁ,  Barva.ŽÁDNÁ);
    }
//%X-



//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
//%X+ <124

    // Sada přístupových metod vlastnosti: Pozice ******************************

    /***************************************************************************
     * Vrátí x-ovou (vodorovnou) souřadnici pozice instance.
     *
     * @return  x-ová souřadnice.
     */
    @Override
    public int getX()
    {
        return krabice.getX();
    }


    /***************************************************************************
     * Vrátí y-ovou (svislou) souřadnici pozice instance.
     *
     * @return  y-ová souřadnice.
     */
    @Override
    public int getY()
    {
        return krabice.getY();
    }

//%X-
//%X+ <125

    /***************************************************************************
     * Vrátí přepravku se svojí aktuální pozicí.
     *
     * @return Aktuální pozice světla
     */
    public Pozice getPozice()
    {
        return new Pozice(getX(), getY());
    }


    /***************************************************************************
     * Nastaví novou pozici světla.
     *
     * @param p Nastavovaná pozice
     */
    public void setPozice(Pozice p)
    {
        this.setPozice(p.x, p.y);
    }

//%X-
//%X+ <123

    /***************************************************************************
     * Nastaví novou pozici instance.
     *
     * @param x   Nová x-ová pozice instance
     * @param y   Nová y-ová pozice instance
     */
//%X-
//%X+ <124
    @Override
//%X-
//%X+ <123
    public void setPozice(int x, int y)
    {
        int modul = krabice.getŠířka();

        krabice.setPozice(x, y);
        červená.setPozice(x, y);
        žlutá  .setPozice(x, y + modul);
        zelená .setPozice(x, y + 2*modul);
    }

//%X-
//%X+ <124

    // Sada přístupových metod vlastnosti: Rozměr / Modul **********************

    /***************************************************************************
     * Vrátí základní délku, od níž se odvozují všechny rozměry objektu -
     * pro semafor je to šířka krabice spolu s průměrem jeho světel.
     *
     * @return Šířka krabice spolu s průměrem světel
     */
    public int getModul()
    {
        return krabice.getŠířka();
    }

//%X-
//%X+ <123

    /***************************************************************************
     * Nastaví nový modul představující šířku krabice a průměr světel.
     *
     * @param modul  Nově nastavovaný modul
     */
    public void setModul(int modul)
    {
        krabice.setRozměr(modul, 3*modul);
        červená.setModul (modul);
        žlutá  .setModul (modul);
        zelená .setModul (modul);

        int x = krabice.getX();
        int y = krabice.getY();
        žlutá  .setPozice(x, y + modul);
        zelená .setPozice(x, y + 2*modul);
    }



//%X-
//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

    /***************************************************************************
     * Projde se semaforem postupně všemi fázemi standardního cyklu, přičemž
     * počet milisekund, po něž semafor setrvá v každé fázi je dán velikostí
     * příslušného parametru.
     *
     * @param stůj      Doba, po níž bude svítit pouze červená
     * @param připravit Doba, po níž bude svítit červená se žlutou
     * @param volno     Doba, po níž bude svítit pouze zelená
     * @param pozor     Doba, po níž bude svítit pouze žlutá
     * @param nic       Doba, po níž budou všechny světla zhasnutá
     */
    public void cyklus(int stůj, int připravit, int volno, int pozor, int nic)
    {
        stůj();         IO.čekej(stůj);
        připravit();    IO.čekej(připravit);
        volno();        IO.čekej(volno);
        pozor();        IO.čekej(pozor);
        zhasni();       IO.čekej(nic);
    }


    /***************************************************************************
     * Projde se semaforem postupně všemi fázemi standardního cyklu, přičemž
     * se v každé fázi "zdrží" půl vteřiny.
     */
    public void cyklus()
    {
        cyklus(500, 500, 500, 500, 500);
    }


    /***************************************************************************
     * Prostřednictvím dodaného kreslítka vykreslí obraz své instance.
     *
     * @param kreslítko Kreslítko, které nakreslí instanci
     */
    @Override
    public void nakresli(Kreslítko kreslítko)
    {
        krabice.nakresli(kreslítko);
        červená.nakresli(kreslítko);
        žlutá  .nakresli(kreslítko);
        zelená .nakresli(kreslítko);
    }


    /***************************************************************************
     * Rozsvítí na semaforu žlutou a zhasne ostatní světla.
     */
    public void pozor()
    {
        červená.zhasni();
        žlutá  .rozsviť();
        zelená .zhasni();
    }


    /***************************************************************************
     * Rozsvítí na semaforu červenou a oranžovou a zhasne zelenou.
     */
    public void připravit()
    {
        červená.rozsviť();
        žlutá  .rozsviť();
        zelená .zhasni();
    }


    /***************************************************************************
     * Rozsvítí na semaforu červenou a zhasne ostatní světla.
     */
    public void stůj()
    {
        červená.rozsviť();
        žlutá  .zhasni();
        zelená .zhasni();
    }


    /***************************************************************************
     * Rozsvítí na semaforu zelenou a zhasne ostatní světla.
     */
    public void volno()
    {
        červená.zhasni();
        žlutá  .zhasni();
        zelená .rozsviť();
    }


    /***************************************************************************
     * Zhasne všechna světla semaforu.
     */
    public void zhasni()
    {
        červená.zhasni();
        žlutá  .zhasni();
        zelená .zhasni();
    }



//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTY A METODA MAIN =======================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        Světlo inst = new Světlo();
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }
}

//%%-  ----- Začátek ignorovaného závěrečného textu -----
////////////////////////////////////////////////////////////////////////////////
//%I+ <121
//%I-

//== TESTY A METODA MAIN =======================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        new Semafor();
//        new Semafor(100, 100);
//        new Semafor(200,  50, Barva.HNĚDÁ);
////        System.exit(0);
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }
}
